unit ExMemo;

interface

uses
Windows, Messages, Classes, StdCtrls;

type

TddgExtendedMemo = class(TMemo)
private
FRow: Longint;
FColumn: Longint;
FOnHScroll: TNotifyEvent;
FOnVScroll: TNotifyEvent;

	procedure WMHScroll(var Msg: TWMHScroll); 
                                                                message WM_HSCROLL;
	procedure WMVScroll(var Msg: TWMVScroll); 
                                                               message WM_VSCROLL;
	procedure SetRow(Value: Longint);
	procedure SetColumn(Value: Longint);
	function GetRow: Longint;
	function GetColumn: Longint;

protected
	procedure HScroll; dynamic;
	procedure VScroll; dynamic;

public

property Row: Longint 
                          read GetRow write SetRow;
property Column: Longint 
	                      read GetColumn write SetColumn;
published
property OnHScroll: TNotifyEvent 
                       read FOnHScroll write FOnHScroll;
property OnVScroll: TNotifyEvent 
                        read FOnVScroll write FOnVScroll;
end;

procedure Register;

implementation

procedure TddgExtendedMemo.WMHScroll(var 
                                                                      Msg: TWMHScroll);
begin
	inherited;
	HScroll;
end;

procedure TddgExtendedMemo.WMVScroll(var 
                                                                      Msg: TWMVScroll);
begin
inherited;
VScroll;
end;

procedure TddgExtendedMemo.HScroll;
begin
if Assigned(FOnHScroll) then
						FOnHScroll(self);
end;

procedure TddgExtendedMemo.VScroll;
begin
	if Assigned(FOnVScroll) then
							FOnVScroll(self);
end;

procedure TddgExtendedMemo.SetRow(Value: Longint);
begin
{Muon at v tr hien hanh cho con nhay ban ch can gi thong iep EM_LINEINDEX en ca so memo. Gia tr wparam la v tr can at. 
Ket qua tra ve tng ng vi v tr SelStart}

     SelStart := Perform(EM_LINEINDEX, Value, 0);
     FRow := SelStart;
end;

function TddgExtendedMemo.GetRow: Longint;
begin
	Result := Perform(EM_LINEFROMCHAR, -1, 0);
end;

procedure TddgExtendedMemo.SetColumn(Value: Longint);
begin
FColumn := Perform(EM_LINELENGTH, Perform(EM_LINEINDEX, GetRow, 0), 0);

if FColumn > Value then
                      FColumn := Value;
SelStart := Perform(EM_LINEINDEX, GetRow, 0) 
                                                                        + FColumn;
end;

function TddgExtendedMemo.GetColumn: Longint;
begin
	Result := SelStart - Perform(EM_LINEINDEX, -1, 0);
end;

procedure Register;
begin
  RegisterComponents('Samples', [TddgExtendedMemo]);
end;

end.
